package mth.masterimp;

import rs.fon.whibo.GC.component.DistanceMeasure.DistanceMeasure;

public class GammaCluster {
	/*
	 * Klasse zur Repräsentation der gamma-Cluster.
	 */

	private int[] member;
	private boolean[] exploredMember;
	private int centroid;

	GammaCluster() {
		member = new int[0];
		exploredMember = new boolean[0];
		centroid = -1;
	}

	GammaCluster(int a) {
		member = new int[a];
		exploredMember = new boolean[a];
		centroid = -1;
	}

	GammaCluster(int[] a) {
		if (a != null && a.length > 0) {
			member = new int[a.length];
			member = a;
			exploredMember = new boolean[a.length];
			centroid = calculateCentroid();
		}
	}

	GammaCluster(int[] a, int c) {
		if (a != null && a.length > 0) {
			member = new int[a.length];
			member = a.clone();
			exploredMember = new boolean[a.length];
		}
		centroid = c;
	}

	public void addMember(int m) {
		int[] helper = new int[member.length + 1];
		boolean[] bhelper = new boolean[exploredMember.length + 1];
		for (int a = 0; a < member.length; a++) {
			helper[a] = member[a];
			bhelper[a] = exploredMember[a];
		}
		helper[member.length] = m;
		bhelper[member.length] = false;
		member = new int[helper.length];
		exploredMember = new boolean[bhelper.length];
		member = helper;
		exploredMember = bhelper;
	}

	public int calculateCentroid() {
		DataRepresentator dr = new DataRepresentator();
		int vmri = member[0];
		if (centroid == -1) {
			double[] mean = new double[dr.getValueMatrix().getNumberOfColumns()
					- dr.getValueMatrix().getNumberOfSpecialColumns()];
			for (int a = 0; a < mean.length; a++) {
				int b = 0;
				while (b < member.length) {
					mean[a] += Double.parseDouble(dr.getValueMatrix().getCell(
							member[b], a));
					b++;
				}
				mean[a] = mean[a] / b;
			}

			try {
				double[] distanceToCenter = new double[member.length];
				DistanceMeasure d = dr.generateDistanceMeasure(
						dr.getDistanceMeasure(), null);
				for (int a = 0; a < member.length; a++) {
					distanceToCenter[a] = d.calculateDistance(mean, Tools
							.extractDoubleArrayFromDataRow(dr.getValueMatrix()
									.getRow(member[a])));
				}
				double centerDistance = distanceToCenter[0];
				for (int a = 0; a < distanceToCenter.length - 1; a++) {
					if (centerDistance < distanceToCenter[a + 1]) {
						vmri = member[a];
						centerDistance = distanceToCenter[a + 1];
					}
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return vmri;
	}

	public boolean containsMember(int x) {
		for (int a = 0; a < member.length; a++) {
			if (member[a] == x)
				return true;
		}
		return false;
	}

	public int getCentroid() {
		return centroid;
	}

	public int getCentroidID() {
		int cID = 0;
		for (int a = 0; a < member.length; a++) {
			if (member[a] == centroid)
				return a;
		}
		return cID;
	}

	public int[] getExploredMember() {
		int[] eM = new int[0];
		for (int a = 0; a < exploredMember.length; a++) {
			if (exploredMember[a])
				eM = Tools.addIntegerToArray(eM, member[a]);
		}
		return eM;
	}

	public int[] getMember() {
		return member;
	}

	public boolean getMemberExplorationState(int m) {
		return exploredMember[m];
	}

	public int getNumberOfMembers() {
		return member.length;
	}

	public int[] getUnexploredMember() {
		int[] ueM = new int[0];
		for (int a = 0; a < exploredMember.length; a++) {
			if (!exploredMember[a])
				Tools.addIntegerToArray(ueM, member[a]);
		}
		return ueM;
	}

	public String printGammaCluster() {
		String outputString = "";
		for (int a = 0; a < member.length; a++) {
			if (a == member.length - 1) {
				outputString += member[a] + "\n";
			} else {
				outputString += member[a] + ",";
			}
		}
		return outputString;
	}

	public void setMemberExploredByID(int id) {
		exploredMember[id] = true;
	}

	public void setMemberExploredByName(int m) {
		for (int a = 0; a < exploredMember.length; a++) {
			if (member[a] == m)
				exploredMember[a] = true;
		}
	}

	public void switchMemberExploredByName(int m) {
		for (int a = 0; a < exploredMember.length; a++) {
			if (member[a] == m)
				exploredMember[m] = (exploredMember[m]) ? false : true;
		}
	}
}
